/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.cef.generator.coreGenerator.base.accessorgen;

import com.inspur.edp.caf.generator.baseInfo.TypeInfo;
import com.inspur.edp.caf.generator.property.ClassPropertyGenerator;
import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.cef.designtime.api.element.GspAssociation;
import com.inspur.edp.cef.gencommon.CefPropertyInfo;
import com.inspur.edp.cef.gencommon.MediateType;
import com.inspur.edp.cef.generator.common.MediatePropertyInfo;
import com.inspur.edp.cef.generator.coreGenerator.base.entitygen.EntityGeneratorContext;
import com.inspur.edp.cef.generator.coreGenerator.base.entitygen.enrichedassoudt.EnrichedGetSetValueGenerator;
import com.inspur.edp.cef.generator.coreGenerator.base.entitygen.enrichedassoudt.OrgAssoUdtPropGenerator;
import com.inspur.edp.cef.generator.coreGenerator.base.entitygen.property.AssoUdtPropGenerator;
import com.inspur.edp.cef.generator.coreGenerator.base.entitygen.property.BaseTypePropGenerator;
import com.inspur.edp.cef.generator.entityGenerator.base.dataTypeData.dataTypePropGen.assoUdt.AssoUdtEnrichedInfoGenerator;
import com.inspur.edp.cef.generator.overall.Utils;
import com.inspur.edp.udt.designtime.api.entity.SimpleDataTypeDef;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

//import com.inspur.edp.cef.rtgenerator.entitygen.enrichedassoudt.OrgAssoUdtPropGenerator;

//    
//    public class BEUserUdtAccessor : ValueObjAccessor, IUserUdt, IBEUserUdt
//    {
//        public BEUserUdtAccessor(IBEUserUdt data) :base(data)
//        { }
//
//        public BEUserInfo Info { get; set; }
//
//        UserInfo IUserUdt.Info
//        {
//            get => Info;
//            set => throw new ReadonlyDataException();
//        }
//
//        public override bool IsReadonly => throw new NotImplementedException();
//
//        public override object getValue(string propName)
//        {
//            throw new NotImplementedException();
//        }
//
//        protected override void acceptChangeCore(IChangeDetail change)
//        {
//            throw new NotImplementedException();
//        }
//    }
//    
public class EnrichedAssoUdtReadonlyAcsGenerator extends ReadOnlyNestedAcsGenerator
{

	private final MediatePropertyInfo propInfo;
	private String parentName;
	private java.util.ArrayList<CefPropertyInfo> udtPropInfos = new java.util.ArrayList<CefPropertyInfo>();

	public EnrichedAssoUdtReadonlyAcsGenerator(EntityGeneratorContext parentContext, MediatePropertyInfo propertyInfo, String parentName) {
		super(parentContext, propertyInfo.getElement().getID(), propertyInfo.getMediateType());
		this.parentName = parentName;
		this.propInfo = propertyInfo;
	}

	@Override
	protected boolean addToMediateTypes(){return false;}

	@Override
	protected void beforeInitialize()
	{
		super.beforeInitialize();
		PropertyInfos.clear();
		IGspCommonField copyElement = propInfo.getElement().clone(propInfo.getElement().getBelongObject(), null);
		copyElement.setIsUdt(false);

		PropertyInfos.add(new MediatePropertyInfo(propInfo.getElement().getLabelID()){{
			setElement(copyElement);
			setPropertyType(AssoUdtEnrichedInfoGenerator.getItemTypeInfo(propInfo.getElement()));
		}});

		IGspCommonField udtField = getudtType().getContainElements().get(0);
		PropertyInfos.add(new MediatePropertyInfo(udtField){{
			setPropertyType(AssoUdtEnrichedInfoGenerator.getItemTypeInfo(udtField));
		}});

		ParentContext.getEnrichedUdtAssoReadonlyAcsTypes().put(
				propInfo.getElement().getLabelID(), new MediateType( "",getName()));
	}

	@Override
	protected final String getName(){
		return (parentName+ propInfo.getElement().getLabelID() + "RDAcc");
	}

	//protected final override BaseTypePropGenerator getBaseTypePropGenerator(CefPropertyInfo propertyInfo)
	//{
	//    if (propertyInfo.DeclaringType == udtType)
	//        return new OrgAssoUdtPropGenerator(enrichedType, propertyInfo);
	//    return base.getBaseTypePropGenerator(propertyInfo);
	//}

//	@Override
//	protected BaseTypePropGenerator getBaseTypePropGenerator(CefPropertyInfo propertyInfo) {
//		if(propertyInfo.getPropertyMethod().equals(infoMethod)) {
//			return new OrgAssoUdtPropGenerator(enrichedType, propertyInfo);
//		}
//		else {
//			return super.getBaseTypePropGenerator(propertyInfo);
//		}
//	}

	@Override
	protected List<BaseTypePropGenerator> getBaseTypePropGenerators(MediatePropertyInfo propertyInfo) {
		List<BaseTypePropGenerator> baseTypePropGenerators = new ArrayList<>();
		if(propertyInfo.getElement().getLabelID().equals(getudtType().getContainElements().get(0).getLabelID())) {
			if(Character.isLowerCase(getudtType().getContainElements().get(0).getLabelID().charAt(0))){
				baseTypePropGenerators.add(new OrgAssoUdtPropGenerator(ParentContext, this.propInfo, true));
			}
			baseTypePropGenerators.add(new OrgAssoUdtPropGenerator(ParentContext, this.propInfo));
			return baseTypePropGenerators;
		} else {
			return super.getBaseTypePropGenerators(propertyInfo);
		}
	}


	@Override
	protected void addExtendPropertyGenerator(ArrayList<ClassPropertyGenerator> proGenerators) {
		super.addExtendPropertyGenerator(proGenerators);
//		proGenerators.add(new OrgAssoUdtPropGenerator(ParentContext, propInfo));

		IGspCommonField udtField = getudtType().getContainElements().get(0);
		GspAssociation udtAsso = udtField.getChildAssociations().get(0);
		boolean contailId = false;

		for (IGspCommonField refField : udtAsso.getRefElementCollection()) {
			if(refField.getLabelID().equals(udtField.getLabelID().concat("_ID")))
				contailId = true;
			MediatePropertyInfo refPropertyInfo = new MediatePropertyInfo(refField) {{
				setPropertyType(Utils.getRefElementPropertyName(refField, udtAsso,
						ParentContext.getProjContext().getCefGenContext()));
			}};
			proGenerators.add(new AssoUdtPropGenerator(ParentContext, refPropertyInfo,
					udtField.getLabelID()));
		}
		if(!contailId){
			MediatePropertyInfo idPropertyInfo = new MediatePropertyInfo(
					udtField.getLabelID().concat("_ID")) {{
				setElement(udtField);
				setExtendInfo("AssoUdtAtrribute", propInfo.getElement().getLabelID());
				setPropertyType(new TypeInfo(String.class));
			}};
			proGenerators.add(new AssoUdtPropGenerator(ParentContext, idPropertyInfo,
					udtField.getLabelID()));
		}
		GspAssociation currentAsso = propInfo.getElement().getChildAssociations().get(0);
		for(IGspCommonField refField : currentAsso.getRefElementCollection()){
			if(refField.getIsFromAssoUdt()){
				continue;
			}
			MediatePropertyInfo refPropertyInfo = new MediatePropertyInfo(refField) {{
				setPropertyType(Utils.getRefElementPropertyName(refField, currentAsso,
						ParentContext.getProjContext().getCefGenContext()));
			}};
			proGenerators.add(new AssoUdtPropGenerator(ParentContext, refPropertyInfo,
					propInfo.getElement().getLabelID()));
		}
		if(Character.isLowerCase(udtField.getLabelID().charAt(0))){
			proGenerators.add(new EnrichedGetSetValueGenerator(udtField, true));
		}
		else {
			proGenerators.add(new EnrichedGetSetValueGenerator(udtField));
		}
	}

	protected final SimpleDataTypeDef getudtType() {
		return ParentContext.getProjContext().getCefGenContext().getMetadataContent(
				propInfo.getElement().getUdtPkgName(), propInfo.getElement().getUdtID());
	}
}
